package com.xzy.d;

import com.xzy.service.impl.StudentServiceImpl;
import com.xzy.service.impl.TeacherServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 说明：Bean生命周期之推断构造器、实例化
 *
 * @author xzy
 * @date 2021/12/5 15:16
 */
@Slf4j
public class Main {
    /*
     * 推断构造器：
     *     1、没有@Autowired标注的构造器
     *         a. 存在无参构造器：调用无参构造器
     *         b. 不存在无参构造器：抛出异常
     *
     *     2、存在多个@Autowired标注的构造器
     *         a. 多个@Autowired(true)：@Autowired(true)表示必须执行，但是Spring又不能同时调用多个构造器，所以抛出异常
     *         b. 多个@Autowired(false)：@Autowired(false)表示可以执行，此时Spring可以自行判断并选择一个最合适的构造器调用
     *            Ⅰ选择参数列表最长，且所有参数都能满足的构造器
     *            Ⅱ如果存在参数列表等长，且所有参数都能满足的构造器，则按照构造器定义顺序选择
     *
     * 如何判断参数列表是否满足：
     *     遍历所有参数，先根据参数类型查找Bean，如果找到多个Bean，则以参数名称为beanName进一步筛选
     */


    public static void main(String[] args) {
        methodE();
    }

    private static void methodA() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(ServiceA.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ServiceA.class));
    }

    private static void methodB() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(ServiceB.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ServiceA.class));
    }

    private static void methodC() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(StudentServiceImpl.class);
        applicationContext.register(TeacherServiceImpl.class);
        applicationContext.register(ServiceC.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ServiceC.class));
    }

    private static void methodD() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(StudentServiceImpl.class);
        applicationContext.register(TeacherServiceImpl.class);
        applicationContext.register(ServiceD.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ServiceD.class));
    }

    private static void methodE() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(StudentServiceImpl.class);
        applicationContext.register(TeacherServiceImpl.class);
        applicationContext.register(ServiceE.class);
        applicationContext.refresh();
        System.out.println(applicationContext.getBean(ServiceE.class));
    }
}
